﻿using System;
using System.Collections.Generic;
using System.Security.Claims;
using Furion;
using Furion.DataEncryption;
using Masuit.Tools.Reflection;
using Microsoft.AspNetCore.Http;
using PMP.Core.Enums;
using PMP.Core.Models;

namespace PMP.Core.Extensions;


public static class JwtHelper
{
    public static JwtTokenModel SetJwt(this JwtUser user)
    {
        var dict = new Dictionary<string, object>();
        foreach (var p in user.GetProperties())
        {
            dict[p.Name] = p.GetValue(user);
        }
        var accessToken = JWTEncryption.Encrypt(dict,24*60);

        // 获取刷新 token
        var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, 43200); 

        // 设置响应报文头
        App.HttpContext.Response.Headers["access-token"] = accessToken;
        App.HttpContext.Response.Headers["x-access-token"] = refreshToken;
        App.HttpContext.SigninToSwagger(accessToken);
        return new JwtTokenModel { AccessToken = accessToken, RefreshToken = refreshToken };
    }
    
    /// <summary>
    /// Returns the value for the first claim of the specified type, otherwise null if the claim is not present.
    /// </summary>
    /// <param name="principal">The <see cref="T:System.Security.Claims.ClaimsPrincipal" /> instance this method extends.</param>
    /// <param name="claimType">The claim type whose first value should be returned.</param>
    /// <returns>The value of the first instance of the specified claim type, or null if the claim is not present.</returns>
    public static T FindFirstValue<T>(this ClaimsPrincipal principal, string claimType)
    {
        var str = principal?.FindFirst(claimType)?.Value;
        return str == null? default(T) : (T)Convert.ChangeType(str, typeof(T));
    }

    /// <summary>
    /// Returns the user ID of the current principal.
    /// </summary>
    /// <param name="principal"></param>
    /// <returns></returns>
    public static int GetUserId(this ClaimsPrincipal principal)
    {
        return principal.FindFirstValue<int>(nameof(JwtUser.UserId));
    }
    public static string GetUserName(this ClaimsPrincipal principal)
    {
        return principal.FindFirstValue<string>(nameof(JwtUser.UserName)) ?? "";
    }
    public static string GetRealName(this ClaimsPrincipal principal)
    {
        return principal.FindFirstValue<string>(nameof(JwtUser.RealName)) ?? "";
    }
    public static EnumUserLevel GetUserLevel(this ClaimsPrincipal principal)
    {
        return (EnumUserLevel)principal.FindFirstValue<int>(nameof(JwtUser.UserLevel));
    }
}